package com.yingoo.controller;

import com.yingoo.api.HttpParam;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.cookie.CookieSpec;
import org.apache.http.cookie.CookieSpecProvider;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.DefaultCookieSpec;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@Service
public class HttpClientUtil {
    private BasicCookieStore cookieStore;
    private HttpClient client;
    @PostConstruct
    public void init(){
        this.cookieStore = new BasicCookieStore();
        CookieSpecProvider myCookie = new CookieSpecProvider() {

            public CookieSpec create(HttpContext context) {
                return new DefaultCookieSpec();
            }
        };
        Registry<CookieSpecProvider> rg = RegistryBuilder.<CookieSpecProvider> create().register("myCookie", myCookie)
                .build();

        this.client = HttpClients.custom().setDefaultCookieStore(cookieStore).setDefaultCookieSpecRegistry(rg).build();
    }

    public HttpClient getClient() {
        return this.client;
    }

    public void getFile(int i) throws UnsupportedEncodingException, URISyntaxException {
        HttpClient httpClient = this.client;
        HttpPost httpPost = new HttpPost();
        httpPost.setURI(new URI("http://www.ximalaya.com/nyx/v1/track/count/web?trackId=43596419"));
        List <NameValuePair> params = new ArrayList<NameValuePair>();
//        params.add(new BasicNameValuePair("trackId", "43596419"));
//        httpPost.addHeader("Host","www.ximalaya.com" );
//        httpPost.addHeader("Origin","http://www.ximalaya.com");
        httpPost.addHeader("Accept","*/*");
        httpPost.addHeader("Accept-Encoding", "gzip, deflate");
        httpPost.addHeader("Accept-Language", "zh-CN,zh;q=0.8");
        httpPost.addHeader("Connection", "keep-alive");
        httpPost.addHeader("Referer","http://www.ximalaya.com/39986840/album/9284267");
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        httpPost.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36");


//        httpPost.setEntity(new UrlEncodedFormEntity(params));
        try {
            HttpResponse response = httpClient.execute(httpPost);
            System.out.println("code:"+response.getStatusLine().getStatusCode());
//            String result = EntityUtils.toString(response.getEntity());
            String cont = readStreamByEncoding(response.getEntity().getContent(), "UTF-8");
            System.out.println("第"+i+"次:"+cont);
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private String readStreamByEncoding(InputStream in, String encoding) throws IOException {
        StringBuffer cont= new StringBuffer();
        BufferedReader br = new BufferedReader(new InputStreamReader(in , encoding));
        String tmp = "";
        while ((tmp = br.readLine())!=null) {
            cont.append(tmp);
        }
        br.close();
        return cont.toString();
    }
    public String getHtmlByProxy(HttpParam param) {
        HttpResponse response = null;
        try {
            HttpRequestBase get = getHttpRequest(param);
            HttpHost httpHost = new HttpHost(param.getIp(),param.getPort());
            RequestConfig requestConfig = RequestConfig.custom() .setProxy(httpHost).build();
//                    setConnectTimeout(2000).
//                    setConnectionRequestTimeout(5000).
//                    setSocketTimeout(5000)
//                           .build();
            get.setConfig(requestConfig);
             response = client.execute(get);
            String result = EntityUtils.toString(response.getEntity(),param.getCharset());
            System.out.println("response-code:"+response.getStatusLine().getStatusCode());
            if(response.getStatusLine().getStatusCode()>=200&&response.getStatusLine().getStatusCode()<300)
                return result;
           else
                return null;
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            EntityUtils.consumeQuietly(response.getEntity());
        }
        return null;
    }

    private HttpGet addHttpGet(HttpParam param) {
        HttpGet get = new HttpGet();
        HashMap<String, String> headers =  param.getHeaders();
        if(headers!=null) {
            Iterator iter = headers.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry) iter.next();
                get.addHeader(entry.getKey(), entry.getValue());
            }
        }

        return get;
    }

    public HttpResponse getResponse(HttpGet httpGet) {
        try {
            return   client.execute(httpGet);
        } catch (IOException e) {
            e.printStackTrace();
            return  null;
        }
    }


    public String getHttpGet(String  url) {
        HttpClient client = this.client;
        HttpGet get = new HttpGet();
        try {
            get.setURI(new URI(url));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        get.addHeader("Accept", "*/*");
        get.addHeader("Accept-Encoding", "gzip, deflate");
        get.addHeader("Accept-Language", "zh-CN,zh;q=0.8");
        get.addHeader("Connection", "keep-alive");
        get.addHeader("Host", "yc.ireader.com.cn");
        get.addHeader("Referer", "http://yc.ireader.com.cn/books/all/default/&page=1");
        get.addHeader("X-Requested-With:", "XMLHttpRequest");
        get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36");
        HttpResponse response = null;
        try {
            response = client.execute(get);
            return EntityUtils.toString(response.getEntity());
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    public String getZRHQHttp(String  url) {
        HttpClient client = this.client;
        HttpGet get = new HttpGet();
        try {
            get.setURI(new URI(url));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        get.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        get.addHeader("Accept-Encoding", "gzip, deflate, sdch");
        get.addHeader("Accept-Language", "zh-CN,zh;q=0.8");
        get.addHeader("Cache-Control","max-age=0");
        get.addHeader("Connection", "keep-alive");
        get.addHeader("Host", "www.ireader.com");
        get.addHeader("Referer", "http://www.ireader.com/index.php");
        get.addHeader("Upgrade-Insecure-Requests","1");
//        get.addHeader("X-Requested-With:", "XMLHttpRequest");
        get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36");
        HttpResponse response = null;
        try {
            response = client.execute(get);
            return EntityUtils.toString(response.getEntity());
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    public Integer getTotalPage(String src) {
        Matcher match = getMatchByPattern(src, "data-page=\".*?\"");
        int maxPage = 0;

        while (match.find()) {
            String page = match.group().replace("data-page=", "").replace("\"", "");
            if(page!=null && !"".equals(page)){
                Integer pageInt = Integer.parseInt(page);
                if (pageInt > maxPage) {
                    maxPage = pageInt;
                }
            }
        }
        return maxPage;
    }

    public HttpRequestBase getHttpRequest(HttpParam param) throws URISyntaxException {
        HttpRequestBase requestBase = null;
        if (param.getMethod()==null||param.getMethod() == 0) {
            requestBase = new HttpGet();
        } else {
            requestBase = new HttpPost();

        }
        HashMap<String, String> headers = param.getHeaders();
            if (headers != null) {
                Iterator iter = headers.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry<String, String> entry = (Map.Entry) iter.next();
                    requestBase.addHeader(entry.getKey(), entry.getValue());
                }
            }
        requestBase.setURI(new URI(param.getUrl()));
        requestBase.addHeader("Accept","*/*");
        requestBase.addHeader("Accept-Encoding", "gzip, deflate");
        requestBase.addHeader("Accept-Language", "zh-CN,zh;q=0.8");
        requestBase.addHeader("Connection", "keep-alive");
        return requestBase;
    }

    public String getHtml(HttpParam param) {

        HttpResponse response = null;
        try {
            HttpRequestBase requestBase = getHttpRequest(param);
            response = client.execute(requestBase);
            if(response.getStatusLine().getStatusCode()>=200&&response.getStatusLine().getStatusCode()<300)
                return EntityUtils.toString(response.getEntity(),param.getCharset());
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (response!=null)
             EntityUtils.consumeQuietly(response.getEntity());
        }
        return null;
    }
    public Matcher getMatchByPattern(String src, String pattern) {
        Pattern p = Pattern.compile(pattern,  Pattern.DOTALL);
        return p.matcher(src);
    }

    public String getStrByPattern(String src, String pattern) {
        Matcher match = getMatchByPattern(src, pattern);
        if(match.find())
            return match.group();
        else
            return  null;
    }

    String parseNumber(String b) {
        if(b==null||b.equals(""))
            return  "0";
        if(b.contains("万")||b.contains("w")) {
            String  src =  b.replace("万", "").replace("w+", "") ;
//
            Double du = Double.parseDouble(src)*10000;
            DecimalFormat decimalFormat = new DecimalFormat("###################.###########");
            return decimalFormat.format(du);

        }
        return b;
    }

    public String postHtml(HttpParam param) {
        HttpPost post = new HttpPost();
        HashMap<String, String> headers =  param.getHeaders();
        if(headers!=null) {
            Iterator iter = headers.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry) iter.next();
                post.addHeader(entry.getKey(), entry.getValue());
            }
        }
        HashMap<String, String> formDate = param.getFormdata();
        if (formDate != null) {
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            Iterator form = formDate.entrySet().iterator();
            while (form.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry) form.next();
                list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            if(list.size() > 0){
                UrlEncodedFormEntity entity = null;
                try {
                    entity = new UrlEncodedFormEntity(list,"utf-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                post.setEntity(entity);
            }
        }
        try {
            post.setURI(new URI(param.getUrl()));
            HttpResponse response = client.execute(post);
//            response.getEntity().
            return EntityUtils.toString(response.getEntity());
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

    public String convert(String utfSrc) {
        StringBuffer sbf = new StringBuffer();
        int i = -1;
        int pos = 0;
        while ((i = utfSrc.indexOf("\\u", pos)) != -1) {
            sbf.append(utfSrc.substring(pos, i));
            if (i + 5 < utfSrc.length()) {
                pos = i+ 6 ;
                sbf.append((char)Integer.parseInt(utfSrc.substring(i + 2, i + 6), 16));

            }
        }
        if (pos < utfSrc.length()) {
            sbf.append(utfSrc.substring(pos, utfSrc.length()));
        }
        return sbf.toString();
    }
}
